#ifndef COOLPOOL_SIMULATION_COLLISIONDETECTIONWORKCOLLECTOR_H_
#define COOLPOOL_SIMULATION_COLLISIONDETECTIONWORKCOLLECTOR_H_

#include <boost/thread.hpp>

#include "Collision.h"
#include "WorldGrid.h"

namespace coolpool
{
	// Work collector for parallel collision detection workers.
	class CollisionDetectionWorkCollector
	{
	public:

		CollisionDetectionWorkCollector();
		virtual ~CollisionDetectionWorkCollector();

		// Differentiates the collisions, and process them, acces to it is synchronized.
		void enqueueCollisionSynchronized(const Collision * col);

		// Returns one collision pair to process.
		// It is not synchronized!!!
		CollisionPair getCollisionPair();

		// Getters:
		// Actual time step for collision time finder.
		inline double getTimeStep()
		{
			return time_step_;
		}

		inline boost::condition_variable * getCond()
		{
			return &cond_;
		}

		inline boost::mutex * getLock()
		{
			return &lock_read_;
		}

		inline bool isEmpty()
		{
			return work_list_->empty();
		}

		// Updates the collision pair list of the next frame, and also the output lists.
		// It is called before start of collision detection in each frame.
		inline void updateWorkList(CollisionPairsQueue * work_list, std::vector<const Collision *> * firsts, std::vector<const Collision *> * resting_contact, double time_step)
		{
			delete work_list_;
			work_list_ = work_list;
			firsts_ = firsts;
			resting_contact_ = resting_contact;
			time_step_ = time_step;
		}

	private:

		// Pairs to proccess.
		CollisionPairsQueue * work_list_;

		// First collisions.
		std::vector<const Collision *> * firsts_;

		// Resting contact collisions.
		std::vector<const Collision *> * resting_contact_;

		// Synchronizing entities:
		boost::condition_variable cond_;

		// Locks the acces to resting_contact_ and firsts.
		boost::mutex lock_write_;

		// Locks the acces to the work list.
		boost::mutex lock_read_;

		double time_step_;
	};
}

#endif
